/*
 * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "sle_hdi_test_entry.h"
#include "sle_adapter_hdi.h"
#include "sle_ssap_server_hdi.h"
#include "sle_unit_test_log.h"

SleSsapsHdiCallbacks *g_ssapsHdiUtCbs;
SleSsapsHdiOpts *g_ssapsHdiUtOpts = NULL;
static uint16_t g_connectId = 0;
static uint8_t g_serverId = 65535;
static SleUuid g_appUuid = {
    .len = 16,
};
static uint16_t g_requestId = 0;

void OnSleHdiUtSsapsStartServiceCallback(uint8_t serverId, uint16_t Handle, SleHdiErrorCode errCode)
{
    SLE_UT_LOG("[SleSsapsHdiTest][PASSED]OnSleHdiUtSsapsStartServiceCallback");
    return;
}

void OnSleHdiUtSsapsDeleteAllServiceCallback(uint8_t serverId, SleHdiErrorCode errCode)
{
    SLE_UT_LOG("[SleSsapsHdiTest][PASSED]OnSleHdiUtSsapsDeleteAllServiceCallback");
    return;
}

void OnSleHdiUtSsapsReadRequestCallback(uint8_t serverId, uint16_t connectId, SsapsReqReadCbParam *readCbPara,
    SleHdiErrorCode errCode)
{
    SLE_UT_LOG("[SleSsapsHdiTest][PASSED]OnSleHdiUtSsapsReadRequestCallback");
    g_requestId = readCbPara->requestId;
    return;
}

void OnSleHdiUtSsapsWriteRequestCallback(uint8_t serverId, uint16_t connectId, SsapsReqWriteCbPara *writeCbPara,
    SleHdiErrorCode errCode)
{
    SLE_UT_LOG("[SleSsapsHdiTest][PASSED]OnSleHdiUtSsapsWriteRequestCallback");
    return;
}

void OnSleHdiUtSsapsMtuChangedCallback(uint8_t serverId, uint16_t connectId,
    SsapMtuInfo *info, SleHdiErrorCode errCode)
{
    SLE_UT_LOG("[SleSsapsHdiTest][PASSED]OnSleHdiUtSsapsMtuChangedCallback");
    return;
}

void GetSleSsapsHdiOptsTestLevel0(void)
{
    SleHdiErrorCode ret = SLE_HDI_ERRCODE_FAIL;
    ret = GetSleSsapsHdiOpts(g_ssapsHdiUtOpts);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HDI_ERRCODE_SUCC, "[SleSsapsHdiTest][FAIL]GetSleSsapsHdiOptsTestLevel0 failed(%08X)", ret);
    SLE_UT_LOG("[SleSsapsHdiTest][PASSED] GetSleSsapsHdiOptsTestLevel0 pass");
}

void SleHdiSsapsRegisterCallbacksTestLevel0(void)
{
    SleHdiErrorCode ret = SLE_HDI_ERRCODE_FAIL;
    ret = g_ssapsHdiUtOpts->registerServerCbks(g_ssapsHdiUtCbs);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HDI_ERRCODE_SUCC, "[SleSsapsHdiTest][FAIL]SleHdiSsapsRegisterCallbacksTestLevel0 failed(%08X)", ret);
    SLE_UT_LOG("[SleSsapsHdiTest][PASSED] SleHdiSsapsRegisterCallbacksTestLevel0 pass");
}

void SleHdiSsapsRegisterServerTestLevel0(void)
{
    SleHdiErrorCode ret = SLE_HDI_ERRCODE_FAIL;
    ret = g_ssapsHdiUtOpts->registerServer(&g_appUuid, &g_serverId);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HDI_ERRCODE_SUCC, "[SleSsapsHdiTest][FAIL]SleHdiSsapsRegisterServerTestLevel0 failed(%08X)", ret);
    SLE_UT_LOG("[SleSsapsHdiTest][PASSED] SleHdiSsapsRegisterServerTestLevel0 pass");
}

static uint16_t g_serviceHandle;
void SleHdiSsapsAddServiceTestLevel0(void)
{
    SleHdiErrorCode ret = SLE_HDI_ERRCODE_FAIL;
    ret = g_ssapsHdiUtOpts->addService(g_serverId, &g_appUuid, true, &g_serviceHandle);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HDI_ERRCODE_SUCC, "[SleSsapsHdiTest][FAIL]SleHdiSsapsAddServiceTestLevel0 failed(%08X)", ret);
    SLE_UT_LOG("[SleSsapsHdiTest][PASSED] SleHdiSsapsAddServiceTestLevel0 pass");
}

static uint16_t g_propertyHandle;
void SleHdiSsapsAddPropertyTestLevel0(void)
{
    SleHdiErrorCode ret = SLE_HDI_ERRCODE_FAIL;
    SsapsPropertyParam propertyParam = {
        
    };
    ret = g_ssapsHdiUtOpts->addProperty(g_serverId, g_serviceHandle, &propertyParam, &g_propertyHandle);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HDI_ERRCODE_SUCC, "[SleSsapsHdiTest][FAIL]SleHdiSsapsAddPropertyTestLevel0 failed(%08X)", ret);
    SLE_UT_LOG("[SleSsapsHdiTest][PASSED] SleHdiSsapsAddPropertyTestLevel0 pass");
}

static uint16_t g_descriptorHandle;
void SleHdiSsapsAddDescriptorTestLevel0(void)
{
    SleHdiErrorCode ret = SLE_HDI_ERRCODE_FAIL;
    uint8_t value[10] = {0};
    SsapsDescriptorParam descriptorParam = {
        .uuid = g_appUuid,
        .permissions = SSAP_PERMISSION_CAN_READ,
        .operateInd = SSAP_OPERATEIND_BIT_READ,
        .type = SLE_SSAP_DESCRIPTOR_TYPE_CUSTOM,
        .valueLen = 10,
        .value = value,
    };
    ret = g_ssapsHdiUtOpts->addDescriptor(g_serverId, g_serviceHandle, g_propertyHandle, &descriptorParam, &g_descriptorHandle);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HDI_ERRCODE_SUCC, "[SleSsapsHdiTest][FAIL]SleHdiSsapsAddDescriptorTestLevel0 failed(%08X)", ret);
    SLE_UT_LOG("[SleSsapsHdiTest][PASSED] SleHdiSsapsAddDescriptorTestLevel0 pass");
}

void SleHdiSsapsStartServiceTestLevel0(void)
{
    SleHdiErrorCode ret = SLE_HDI_ERRCODE_FAIL;
    ret = g_ssapsHdiUtOpts->startService(g_serverId, g_serviceHandle);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HDI_ERRCODE_SUCC, "[SleSsapsHdiTest][FAIL]SleHdiSsapsStartServiceTestLevel0 failed(%08X)", ret);
    SLE_UT_LOG("[SleSsapsHdiTest][PASSED] SleHdiSsapsStartServiceTestLevel0 pass");
}

void SleHdiSsapsSendResponseTestLevel0(void)
{
    SleHdiErrorCode ret = SLE_HDI_ERRCODE_FAIL;
    uint8_t value[10] = {0};
    SsapsSendRspParam sendRspParam = {
        .requestId = g_requestId,
        .valueLen = 10,
        .value = value,
    };
    ret = g_ssapsHdiUtOpts->sendResponse(g_serverId, g_connectId, &sendRspParam);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HDI_ERRCODE_SUCC, "[SleSsapsHdiTest][FAIL]SleHdiSsapsSendResponseTestLevel0 failed(%08X)", ret);
    SLE_UT_LOG("[SleSsapsHdiTest][PASSED] SleHdiSsapsSendResponseTestLevel0 pass");
}

void SleHdiSsapsNotifyIndicateTestLevel0(void)
{
    SleHdiErrorCode ret = SLE_HDI_ERRCODE_FAIL;
    uint8_t value[10] = {0};
    SsapsNotifyParam notifyParam = {
        .handle = g_propertyHandle,
        .type = SSAP_PROPERTY_TYPE_VALUE_TYPE,
        .valueLen = 10,
        .value = value,
    };
    ret = g_ssapsHdiUtOpts->sendNotifyIndicate(g_serverId, g_connectId, &notifyParam);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HDI_ERRCODE_SUCC, "[SleSsapsHdiTest][FAIL]SleHdiSsapsNotifyIndicateTestLevel0 failed(%08X)", ret);
    SLE_UT_LOG("[SleSsapsHdiTest][PASSED] SleHdiSsapsNotifyIndicateTestLevel0 pass");
}

void SleHdiSsapsNotifyIndicateByUuidTestLevel0(void)
{
    SleHdiErrorCode ret = SLE_HDI_ERRCODE_FAIL;
    uint8_t value[10] = {0};
    SsapsNotyfyByUuidParam notifyByUuidParam = {
        .uuid = g_appUuid,
        .startHandle = 0,
        .endHandle = 100,
        .type = SSAP_PROPERTY_TYPE_VALUE_TYPE,
        .valueLen = 10,
        .value = value,
    };
    ret = g_ssapsHdiUtOpts->sendNotifyIndicateByUuid(g_serverId, g_connectId, &notifyByUuidParam);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HDI_ERRCODE_SUCC, "[SleSsapsHdiTest][FAIL]SleHdiSsapsNotifyIndicateByUuidTestLevel0 failed(%08X)", ret);
    SLE_UT_LOG("[SleSsapsHdiTest][PASSED] SleHdiSsapsNotifyIndicateByUuidTestLevel0 pass");
}

void SleHdiSsapsSetInfoTestLevel0(void)
{
    SleHdiErrorCode ret = SLE_HDI_ERRCODE_FAIL;
    SsapMtuInfo mtuInfo = {
        .mtuSize = 300,
        .version = 1,
    };
    ret = g_ssapsHdiUtOpts->setServerMtuInfo(g_serverId, &mtuInfo);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HDI_ERRCODE_SUCC, "[SleSsapsHdiTest][FAIL]SleHdiSsapsSetInfoTestLevel0 failed(%08X)", ret);
    SLE_UT_LOG("[SleSsapsHdiTest][PASSED] SleHdiSsapsSetInfoTestLevel0 pass");
}

void SleHdiSsapsDeleteAllServicesTestLevel0(void)
{
    SleHdiErrorCode ret = SLE_HDI_ERRCODE_FAIL;
    ret = g_ssapsHdiUtOpts->deleteAllServices(g_serverId);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HDI_ERRCODE_SUCC, "[SleSsapsHdiTest][FAIL]SleHdiSsapsDeleteAllServicesTestLevel0 failed(%08X)", ret);
    SLE_UT_LOG("[SleSsapsHdiTest][PASSED] SleHdiSsapsDeleteAllServicesTestLevel0 pass");
}

void SleHdiSsapsUnregisterServerTestLevel0(void)
{
    SleHdiErrorCode ret = SLE_HDI_ERRCODE_FAIL;
    ret = g_ssapsHdiUtOpts->unregisterServer(g_serverId);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HDI_ERRCODE_SUCC, "[SleSsapsHdiTest][FAIL]SleHdiSsapsUnregisterServerTestLevel0 failed(%08X)", ret);
    SLE_UT_LOG("[SleSsapsHdiTest][PASSED] SleHdiSsapsUnregisterServerTestLevel0 pass");
}

void SleSsapsHdiTestLevel0(void)
{
    GetSleSsapsHdiOptsTestLevel0();
    SleHdiSsapsRegisterCallbacksTestLevel0();
    SleHdiSsapsRegisterServerTestLevel0();
    SleHdiSsapsAddServiceTestLevel0();
    SleHdiSsapsAddPropertyTestLevel0();
    SleHdiSsapsAddDescriptorTestLevel0();
    SleHdiSsapsStartServiceTestLevel0();
    SleHdiSsapsSendResponseTestLevel0();
    SleHdiSsapsNotifyIndicateTestLevel0();
    SleHdiSsapsNotifyIndicateByUuidTestLevel0();
    SleHdiSsapsSetInfoTestLevel0();
    SleHdiSsapsDeleteAllServicesTestLevel0();
    SleHdiSsapsUnregisterServerTestLevel0();
}

SleHdiErrorCode InitSleSsapsHdiTestEntry(void)
{
    g_ssapsHdiUtCbs = (SleSsapsHdiCallbacks*)malloc(sizeof(SleSsapsHdiCallbacks));
    SLE_UT_CHECK_AND_RETURN_RET_LOG(g_ssapsHdiUtCbs != NULL, SLE_HDI_ERRCODE_FAIL, "[SleSsapsHdiTest][FAILED]InitSleSsapsHdiTestEntry malloc failed");
    g_ssapsHdiUtOpts = (SleSsapsHdiOpts*)malloc(sizeof(SleSsapsHdiOpts));
    SLE_UT_CHECK_AND_RETURN_RET_LOG(g_ssapsHdiUtOpts != NULL, SLE_HDI_ERRCODE_FAIL, "[SleSsapsHdiTest][FAILED]InitSleSsapsHdiTestEntry memset failed");
    g_ssapsHdiUtCbs->OnServiceStartedCb = OnSleHdiUtSsapsStartServiceCallback;
    g_ssapsHdiUtCbs->OnAllServiceRemovedCb = OnSleHdiUtSsapsDeleteAllServiceCallback;
    g_ssapsHdiUtCbs->OnRecvReadReqCb = OnSleHdiUtSsapsReadRequestCallback;
    g_ssapsHdiUtCbs->OnRecvWriteReqCb = OnSleHdiUtSsapsWriteRequestCallback;
    g_ssapsHdiUtCbs->OnMtuChangedCb = OnSleHdiUtSsapsMtuChangedCallback;
    uint8_t uuid[UUID_LEN] = {1};
    memcpy(g_appUuid.uuid, uuid, UUID_LEN);
    return SLE_HDI_ERRCODE_SUCC;
}

SleHdiErrorCode DeinitSleSsapsHdiTestEntry(void)
{
    free(g_ssapsHdiUtOpts);
    free(g_ssapsHdiUtCbs);
    return SLE_HDI_ERRCODE_SUCC;
}

void SleSsapsHdiTestEntry(void)
{
    SLE_UT_LOG("__SleSsapsHdiTestEntry start");
    SleHdiErrorCode ret = SLE_HDI_ERRCODE_FAIL;
    ret = InitSleSsapsHdiTestEntry();
    SLE_UT_CHECK_AND_RETURN(ret == SLE_HDI_ERRCODE_SUCC);
    SleSsapsHdiTestLevel0();
    // SleSsapsHdiTestLevel1();
    ret = DeinitSleSsapsHdiTestEntry();
    SLE_UT_CHECK_AND_RETURN(ret == SLE_HDI_ERRCODE_SUCC);
    SLE_UT_LOG("__SleSsapsHdiTestEntry end");
}
